package org.hisp.dhis.wsclient.j2me.javarosa;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Stack;
import java.util.Vector;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;

import org.hisp.dhis.wsclient.dao.OrganisationUnitDAO;
import org.hisp.dhis.wsclient.dao.mockup.MockupOrganisationUnitDAO;
import org.hisp.dhis.wsclient.model.OrganisationUnit;
import org.javarosa.core.Context;
import org.javarosa.core.api.Constants;
import org.javarosa.core.api.IActivity;
import org.javarosa.core.api.IShell;

import de.enough.polish.ui.Choice;
import de.enough.polish.ui.ChoiceItem;

public class SelectOrganisationUnitActivity
    implements IActivity, CommandListener
{

    private IShell shell;
    private Keys keys;
    private Context context;

    private Command cmdSelect;
    private Command cmdBack;

    private OrganisationUnitDAO orgunitDAO;
    private Stack levels;

    public SelectOrganisationUnitActivity( IShell shell, Keys keys )
    {
        setShell( shell );
        this.keys = keys;

        cmdSelect = new Command( "Select", Command.OK, 0 );
        cmdBack = new Command( "Back", Command.BACK, 1 );

        orgunitDAO = new MockupOrganisationUnitDAO();
    }

    public void contextChanged( Context globalContext )
    {
        // TODO Auto-generated method stub

    }

    public void destroy()
    {
        // TODO Auto-generated method stub

    }

    public Context getActivityContext()
    {
        // TODO Auto-generated method stub
        return null;
    }

    public void halt()
    {
        // TODO Auto-generated method stub

    }

    public void resume( Context globalContext )
    {
        // TODO Auto-generated method stub

    }

    public void setShell( IShell shell )
    {
        this.shell = shell;
    }

    public void start( Context context )
    {
        this.context = context;
        levels = new Stack();
        pushLevel( null, null );
    }

    private void pushLevel( OrganisationUnit parent, Vector children )
    {
        Level level = new Level();

        if ( children == null )
        {
            children = orgunitDAO.listOrganisationUnits( parent );
        }
        level.orgunits = children;
        level.screen = createScreen( parent, children );
        level.parent = parent;

        levels.push( level );
        displayCurrentScreen();
    }

    private FilteredListContains createScreen( OrganisationUnit parent, Vector children )
    {
        String title;
        if ( parent == null )
        {
            title = "Select organisation unit";
        }
        else
        {
            title = "Select child of '" + parent.getName() + "'";
        }

        if ( children == null )
        {
            children = new Vector();
        }

        //#style .filteredListScreen, .listScreen, .baseScreen
        FilteredListContains list = new FilteredListContains( title, FilteredListContains.IMPLICIT );

        list.addCommand( cmdSelect );
        list.addCommand( cmdBack );

        OrganisationUnit orgunit;
        for ( Enumeration e = children.elements(); e.hasMoreElements(); )
        {
            orgunit = (OrganisationUnit) e.nextElement();
            //#style .filteredListItem, .listItem, .item
            ChoiceItem choice = new ChoiceItem( orgunit.getName(), null, Choice.IMPLICIT );
            choice.setDefaultCommand( cmdSelect );
            list.append( choice );
        }
        list.setCommandListener( this );

        return list;
    }

    public void commandAction( Command cmd, Displayable display )
    {
        if ( cmd == FilteredListContains.SELECT_COMMAND )
        {
            Level level = (Level) levels.peek();
            FilteredListContains list = level.screen;
            OrganisationUnit selectedOrgunit = (OrganisationUnit) level.orgunits.elementAt( list.getSelectedIndex() );

            // Determine if selected orgunit has any children
            Vector children = orgunitDAO.listOrganisationUnits( selectedOrgunit );
            if ( children.size() > 0 )
            {
                pushLevel( selectedOrgunit, children );
            }
            else
            {
                Hashtable returnVals = new Hashtable();
                returnVals.put( keys.ORGUNIT, selectedOrgunit );
                shell.returnFromActivity( this, Constants.ACTIVITY_COMPLETE, returnVals );
            }
        }
        else if ( cmd == cmdBack )
        {
            levels.pop();

            if ( levels.empty() )
            {
                shell.returnFromActivity( this, Constants.ACTIVITY_CANCEL, null );
            }
            else
            {
                displayCurrentScreen();
            }
        }

    }

    private void displayCurrentScreen()
    {
        Level level = (Level) levels.peek();
        shell.setDisplay( this, Util.createIView( level.screen ) );
    }

    private class Level
    {
        public FilteredListContains screen;
        public OrganisationUnit parent;
        public Vector orgunits;
    }
}
